package com.demo.controls;

import gl.java.pay.IPay;
import gl.java.pay.PayFactory;
import gl.java.pay.alipay.AliPay;
import gl.java.pay.alipay.util.AlipayNotify;

import java.security.InvalidKeyException;
import java.security.spec.InvalidKeySpecException;
import java.sql.Date;
import java.util.HashMap;
import java.util.List;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.log4j.Logger;

import com.chanceit.framework.utils.encode.Des;
import com.demo.common.model.Payment;
import com.demo.common.model.Userorder;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.log.Log;

public class PayOrderController extends BaseController {
	private static final Logger logger = Logger.getLogger("PayOrderController");
	private static long ODER_VALUE_TIME = 15 * 60 * 1000;
	static final String GLSIGN = "glsign";

	public void index() {
		int userid;
		if ((userid = checkToken()) < 0) {
			return;
		}
		String orderidString = getPara("orderid", "");
		if (isEmpty(orderidString)) {
			renderErr("orderid is null");
			return;
		}
		int[] orderids = getParToIntArray(orderidString);
		if (orderids == null) {
			renderErr("orderid parse err");
			return;
		}
		for (int i = 0; i < orderids.length; i++) {
			Userorder order = Userorder.dao.findById(orderids[i]);
			if (order == null) {
				renderErr("订单不存在");
				return;
			}
			if (order.getFuserid().intValue() != userid) {
				renderErr("订单与用户不匹配");
				return;
			}
			if (order.getIspay().intValue() == TRUE) {
				renderErr("订单已经支付");
				return;
			}
		}

		// TODO 支付 涉及多人支付.
		Payment payment;
		List<Payment> list = Payment.dao.find(
				"select * from payment where orderids = ?", orderidString);
		if (list == null || list.size() <= 0) {
			payment = new Payment();
		} else if (list.size() == 1) {
			payment = list.get(0);
		} else {
			renderErr("Inner Error ,orderid " + orderidString
					+ " not should be same in payment");
			return;
		}
		payment.setCreatetime(new Date(System.currentTimeMillis()));
		payment.setEndtime(new Date(System.currentTimeMillis()
				+ ODER_VALUE_TIME));
		payment.setFuserid(userid);
		payment.setIspay(DOING);
		int paytype = getParaToInt("paytype", 0);
		payment.setPaytype(paytype);
		payment.setOrderids(orderidString);
		int Totalprice = 0;
		for (int i = 0; i < orderids.length; i++) {
			Totalprice += Userorder.dao.findById(orderids[i]).getTotalprice();
		}
		payment.setTotalprice(Totalprice);
		if (payment.getId() == null) {
			payment.save();
		}
		String paymentinfo = "";
		IPay payer = null;
		switch (paytype) {
		case PAYTYPE_ALI_MOBLIE:
			payer = new PayFactory<AliPay>().create(AliPay.class);
			break;
		case PAYTYPE_BLANCE:// TODO PAYTYPE_BLANCE
		case PAYTYPE_WEIXIN_MOBLIE:// TODO PAYTYPE_WEIXIN_MOBLIE
		default:
			renderErr("不支持的订单方式:" + paytype);
			return;
		}
		payment.setCallback(PropKit.get("payCallBackHost")
				+ "/payorder/payCallBack?paymentid=" + payment.getId()
				+ "&paytype=" + paytype+"&"+GLSIGN+"="+genPaySign(payment.getId()));
		paymentinfo = payer.genPayInfo(orderidString, "水果日历商品", "鲜美的水果",
				String.valueOf(((float) Totalprice) / 100),
				payment.getCallback());
		String deCrypto = hidePayinfo(paymentinfo);
		payment.setPayinfo(paymentinfo);
		payment.update();
		payment.setPayinfo(deCrypto);
		renderJson(payment);
	}
	/**
	 * 根据种子生成一个签名
	 * @param id 种子
	 * @return
	 */
	private static String genPaySign(int id) {
		return Des.enCrypto(new StringBuilder().append(id+"x"+id+"xx"+id+"xxx"+id).toString());
	}
	/**
	 * 根据种子校验签名
	 * @param sign 签名内容
	 * @param id 种子
	 * @return
	 */
	private static boolean vefyPaySign(String sign,int id) {
		try {
			String deCrypto = Des.deCrypto(sign);
			return Integer.parseInt(deCrypto.split("x")[0]) == id;
		} catch (Exception e) {
			logger.error(e);
			return false;
		}
	}
//	public static void main(String[] args) {
//		for (int i = 994; i < 1021; i++) {
//			String genPaySign = genPaySign(i);
//			System.out.println(genPaySign);
//			System.out.println(vefyPaySign(genPaySign,i));
//		}
//	}
	/**
	 * 对帐号进行加密,使得在传输过程中别截取依然不能看到敏感信息
	 * @param paymentinfo
	 * @return
	 */
	public String hidePayinfo(String paymentinfo) {
		String deCrypto;
		try {
			deCrypto = Des.enCrypto(paymentinfo,
					PropKit.get("PublicDes", "xusanduo"));
			return deCrypto;
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (InvalidKeySpecException e) {
			e.printStackTrace();
		} catch (NoSuchPaddingException e) {
			e.printStackTrace();
		} catch (IllegalBlockSizeException e) {
			e.printStackTrace();
		} catch (BadPaddingException e) {
			e.printStackTrace();
		}
		return "hide fail";
	}

	public void payCallBack() {
		int paymentid = getParaToInt("paymentid", -1);
		if (paymentid < 0) {
			renderErr("not a payment callback");
			return;
		}
		int paytype = getParaToInt("paytype", 0);
		if (PAYTYPE_ALI_MOBLIE == paytype ) {
			if (handlerAlipayCallBack(this)&&vefyPaySign(getPara(GLSIGN,""),paymentid)) {
				setPayComplete(paymentid,getPara());
			} else {
				renderErr("handlerAlipayCallBack fail .read the log");
				return;
			}
		} else if (2==paytype) {
			renderErr("WeiXin Pay is unable");
			return;
		} else {
			renderErr("this Pay is unable");
			return;
		}

	}

	public void setPayComplete(int paymentid,String thirdCallBackInfo) {
		Payment payment = Payment.dao.findById(paymentid);
		if (payment == null) {
			renderErr("支付订单不存在 " + paymentid);
			logger.error("paymentid " + paymentid + " can not be found");
			return;
		}

		if (payment.getIspay().intValue() != TRUE) {
			payment.setIspay(TRUE);
			payment.setThirdcallbackinfo(getRequest().getRemoteHost()+":"+getRequest().getRemotePort()+"->"+thirdCallBackInfo);
			if (!payment.update()) {
				renderErr("充值到帐保存失败 " + paymentid);
				Log.getLog(this.getClass()).error(
						"paymentid " + payment + " update fial");
				return;
			}
			int[] orderids = getParToIntArray(payment.getOrderids());
			if (orderids == null) {
				renderErr("orderid parse err");
				return;
			}
			for (int i = 0; i < orderids.length; i++) {
				Userorder order = Userorder.dao.findById(orderids[i]);
				if (order == null) {
					renderErr("订单不存在");
					logger.error("order not exist "+orderids[i]);
					continue;
				}
				if (order.getFuserid().intValue() != order.getFuserid()) {
					renderErr("订单与用户不匹配");
					logger.error("order not match the user "+orderids[i]);
					continue;
				}
				if (order.getIspay().intValue() == TRUE) {
					renderErr("订单已经支付");
					logger.error("order has pay "+ orderids[i]);
					continue;
				}
				order.setIspay(TRUE);
				if (!order.update()) {
					renderErr("充值到帐刷新订单失败 " + order.getId());
					logger.error("order update fail ,DB err " + orderids[i]);
					continue;
				}
			}

		} else {
			logger.debug("payment has pay");
		}
	}

	// to pay server
	// partner="2088502990467974"&seller_id="1031320252@qq.com"&out_trade_no="0720003835-7681"&subject="水果日历商品"&body="鲜美的水果"&total_fee="0.0"
	// &notify_url="http://shuiguorili.com:8080/payCallBack?paymentid=3"&service="mobile.securitypay.pay"&payment_type="1"&_input_charset="utf-8"&it_b_pay="30m"&return_url="m.alipay.com"&sign="N7oiXJr8t4jBcWMvtAHEnYoTZVYQomVou3G0DAmcAi5OQhdJzJx52IHvCwzc2qDKWBFzEZa67h%2FNHXuJbkjdJXzjJ2WpMaQeixV%2BYFkB%2FFbnL1ForEUbP5k6KLu5I5lbXpU8JYh9jojkFrxCy62MyBCmP1uOtO7S2SZifPikyEw%3D"&sign_type="RSA"

	// paymentid=16 discount=0.00 payment_type=1 subject=??????
	// trade_no=2016072021001004170203184326 buyer_email=18672960052
	// gmt_create=2016-07-20 23:12:39 notify_type=trade_status_sync quantity=1
	// out_trade_no=0720231234-4281 seller_id=2088502990467974
	// notify_time=2016-07-20 23:12:40 body=????? trade_status=TRADE_SUCCESS
	// is_total_fee_adjust=N total_fee=0.05 gmt_payment=2016-07-20 23:12:40
	// seller_email=1031320252@qq.com price=0.05 buyer_id=2088702053944174
	// notify_id=452ea390df8ac5eab31025bf40a9d36hba use_coupon=N sign_type=RSA
	// sign=NIWoVtyWTpisWemvYbUtlnalm9Li+Uv3VNigTwjudWEpvjHQZsAqv3qvkPTeuoiQz9/1Txqwo4wKxMO5TeMXw7ugghSOs3m78MNd2aZpBmOHbrCPi9glrsnNUvmHgXFgQkErxnSMuPBbeIy1wJWWhet/pm+6pSxLE2mWAwmNFJ4=
	private boolean handlerAlipayCallBack(Controller payOrderController) {
		if ("TRADE_SUCCESS".equals(getPara("trade_status", ""))) {
			HashMap<String, String> parMap = getParMap(payOrderController);
			if (AlipayNotify.verify(parMap)) {
				payOrderController.renderText("success");
				return true;
			}else{
				logger.error("AlipayNotify.verify(parMap) fail");
			}
		}

		return false;
	}

}